home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / source / fbm12s.lha / fbps.c < prev    next >
C/C++ Source or Header  |  1994-07-18  |  9KB  |  292 lines

  1. /****************************************************************
  2.  * fbps.c: FBM Release 1.2 02-Jun-93 Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989-1993 by Michael Mauldin.  Permission is granted
  5.  * to use this file in whole or in part for any purpose, educational,
  6.  * recreational or commercial, provided that this copyright notice
  7.  * is retained unchanged.  This software is available to all free of
  8.  * charge by anonymous FTP and in the UUNET archives.
  9.  *
  10.  * fbps: Convert a grayscale image to a PostScript file
  11.  *
  12.  * USAGE
  13.  *    % fbps < image > postscript
  14.  *
  15.  * EDITLOG
  16.  *    LastEditDate = Mon Jun 25 00:04:03 1990 - Michael Mauldin
  17.  *    LastFileName = /usr2/mlm/src/misc/fbm/fbps.c
  18.  *
  19.  * HISTORY
  20.  * 02-Jun-93  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  21.  *    Add ability to handle mapped/unmapped 1,4,8 bit grayscale and color.
  22.  *
  23.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  24.  *    Package for Release 1.0
  25.  *
  26.  * 26-Aug-89  Paul Milazzo (milazzo) at BBN
  27.  *    Beta release (version 0.96)
  28.  *    Added rotation, big paper option
  29.  *
  30.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  31.  *    Beta release (version 0.94) mlm@cs.cmu.edu
  32.  *
  33.  * 25-Apr-89  Paul Milazzo (milazzo) at BBN
  34.  *    Added color postscript support
  35.  *
  36.  * 27-Aug-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  37.  *    Created.
  38.  *****************************************************************/
  39.  
  40. # include <stdio.h>
  41. # include <math.h>
  42. # include "fbm.h"
  43.  
  44. # define PAPERWIDTH 8.5 /* inches */
  45. # define BIGPAPERWIDTH 11 /* inches */
  46. # define PAPERHEIGHT 11 /* inches */
  47. # define BIGPAPERHEIGHT 14 /* inches */
  48.  
  49. char *ps_chars();
  50.  
  51. # define USAGE \
  52. "Usage: fbps [-t<title> -c<credits> -b<banner> -d<dpi> [-pP] [ -rsL ] [ -w<width> ] < foo.fbm > foo.PS"
  53.  
  54. #ifndef lint
  55. static char *fbmid =
  56. "$FBM fbps.c <1.0> 25-Jun-90  (C) 1989,1990 by Michael Mauldin, source \
  57. code available free from MLM@CS.CMU.EDU and from UUNET archives$";
  58. #endif
  59.  
  60. int resolution = 300; /* dpi */
  61.  
  62. main (argc, argv)
  63. char *argv[];
  64. { register int i, j;
  65.   int rows, cols, rowlen;
  66.   double paperwidth, paperheight;
  67.   double maxwidth, maxheight;
  68.   double width = -1, height, llx, lly, top, bottom;
  69.   int bytcnt=0, bigpaper=0, dobanner=1, dotitle=1, docredits=1, dosize=1;
  70.   int rotate=0, scribe=0, compressed=0;
  71.   char buf[BUFSIZ];
  72.   char *banner=NULL, *title=NULL, *credits=NULL, *creator=NULL;
  73.   long clock = time ((long *) NULL);
  74.   char *ctime ();
  75.   FBM image;
  76.   int iscolor, bits, padlen;
  77.  
  78.   /* Clear the memory pointer so alloc_fbm won't be confused */
  79.   image.cm  = image.bm  = (unsigned char *) NULL;
  80.  
  81.   /* Get the options */
  82.   while (--argc > 0 && (*++argv)[0] == '-')
  83.   { while (*++(*argv))
  84.     { switch (**argv)
  85.       { case 'b':    banner = *argv+1; dobanner = 1; SKIPARG; break;
  86.     case 'B':    dobanner = 0; break;
  87.     case 't':    title = *argv+1; dotitle = 1; SKIPARG; break;
  88.     case 'T':    dotitle = 0; break;
  89.     case 'c':    credits = *argv+1; docredits = 1; SKIPARG; break;
  90.     case 'C':    docredits = 0; break;
  91.     case 'p':    dosize = 1; break;
  92.     case 'P':    dosize = 0; break;
  93.     case 'r':    rotate++; break;
  94.     case 'd':    resolution = atoi (*argv+1); SKIPARG; break;
  95.     case 'L':    bigpaper++; break;
  96.     case 's':    scribe++; break;
  97.     case 'w':    width = atof (*argv+1); SKIPARG; break;
  98.     default:    fprintf (stderr, "%s\n", USAGE);
  99.             exit (1);
  100.       }
  101.     }
  102.   }
  103.  
  104.   if (!read_bitmap (&image, (char *) NULL))
  105.   { exit (1); }
  106.  
  107.   /* Get title */
  108.   if (!title && image.hdr.title && image.hdr.title[0])
  109.   { title = image.hdr.title; }
  110.  
  111.   /* Get credits */
  112.   if (!credits && image.hdr.credits && image.hdr.credits[0])
  113.   { credits = image.hdr.credits; }
  114.  
  115.   /* Get width and height */
  116.   rows = image.hdr.rows;
  117.   cols = image.hdr.cols;
  118.   rowlen = image.hdr.rowlen;
  119.  
  120.   paperwidth = bigpaper ? BIGPAPERWIDTH : PAPERWIDTH;
  121.   paperheight = bigpaper ? BIGPAPERHEIGHT : PAPERHEIGHT;
  122.  
  123.   maxwidth = (rotate ? paperheight : paperwidth) - 1.49;
  124.   maxheight = (rotate ? paperwidth : paperheight) - 1.49;
  125.  
  126.   analyze_image (&image, &iscolor, &bits, &padlen);
  127.  
  128.   /*==== Choose X and Y size, if width not specified ====*/
  129.   if (bits == 1)
  130.   { int scalex, scaley, rscale;
  131.     double rwidth, rheight;
  132.   
  133.     scalex = (maxwidth * resolution) / cols;
  134.     scaley = (maxheight * resolution) / rows;
  135.     rscale = (scalex < scaley) ? scalex : scaley;
  136.     
  137.     if (rscale < 1)
  138.     { fprintf (stderr,
  139.            "Error: image too large [%d,%d] to fit at %d dpi resolution\n",
  140.            cols, rows, resolution);
  141.       exit (1);
  142.     }
  143.     
  144.     width = (double) cols * rscale / (double) resolution;
  145.     height = (double) rows * rscale / (double) resolution;
  146.   }
  147.   else
  148.   { if (width < 0.0 || width > maxwidth)
  149.     { width = maxwidth; }
  150.  
  151.     height = width * image.hdr.aspect * (double) rows / cols;
  152.  
  153.     if (height > maxheight)
  154.     { width = width * maxheight / height; height = maxheight; }
  155.   }
  156.  
  157.   /* Pick lower left corner */
  158.   if (scribe)
  159.   { llx = lly = 0.0;  }
  160.   else
  161.   { llx = (paperwidth - (rotate ? height : width)) / 2.0;
  162.     lly = rotate ? width + ((paperheight - width) / 2.0) :
  163.            (paperheight - height) / 2.0;
  164.   }
  165.  
  166.   fprintf (stderr,
  167.        "FBM to PS \"%s\" width %1.3lf inches, height %1.3lf inches\n",
  168.        title ? title : "(untitled)", width, height);
  169.  
  170.   /* Write out PostScript Header */
  171.   if (scribe)
  172.   { printf ("%%! Scribe @graphic style PostScript\n");
  173.     if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
  174.     if (banner) { printf ("%%%%Banner: %s\n", ps_chars (banner)); }
  175.     if (credits) { printf ("%%%%Credits: %s\n", ps_chars (credits)); }
  176.     if (creator) { printf ("%%%%Creator:  %s\n", ps_chars (creator)); }
  177.     printf ("%%%%CreationDate: %s", ctime (&clock));
  178.  
  179.     printf ("/inch { 72 mul } def\n");
  180.     printf ("/picstr %d string def\n\n", BYTESPERLINE);
  181.     dotitle = dosize = 0;
  182.   }
  183.   else
  184.   { printf ("%%!PS-Adobe-1.0\n");
  185.     if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
  186.     if (banner) { printf ("%%%%Banner: %s\n", ps_chars (banner)); }
  187.     if (credits) { printf ("%%%%Credits: %s\n", ps_chars (credits)); }
  188.     if (creator) { printf ("%%%%Creator:  %s\n", ps_chars (creator)); }
  189.     printf ("%%%%CreationDate: %s", ctime (&clock));
  190.     printf ("%%%%Pages: 1\n");
  191.     printf ("%%%%DocumentFonts:%s%s\n",
  192.         dotitle ? " Times-Bold" : "",
  193.         dosize ?  " Times-Roman" : "");
  194.     printf ("%%%%EndComments\n");
  195.     printf ("%%%%EndProlog\n");
  196.     printf ("%%%%Page: 1 1\n\n");
  197.  
  198.     printf ("/inch { 72 mul } def\n");
  199.     printf ("/picstr %d string def\n\n", BYTESPERLINE);
  200.  
  201.   }
  202.  
  203.   printf ("gsave\n");
  204.  
  205.   if (llx != 0.0 || lly != 0.0)
  206.   { printf ("%lg inch %lg inch translate", llx, lly); }
  207.  
  208.   if (rotate)
  209.   { fputs (" -90 rotate", stdout);  }
  210.  
  211.   printf ("\n\n");
  212.  
  213.   top = height + 0.125; 
  214.   bottom = -0.125;
  215.  
  216.   if (dotitle && title)
  217.   { printf ("/Times-Bold findfont 14 scalefont setfont\n");
  218.     printf ("%lg inch %lg inch moveto\n", width/2.0, top);
  219.     printf ("(%s)\n", ps_chars (title));
  220.     printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
  221.     top += (14.0 / 72.0) + 0.125;
  222.   }
  223.  
  224.   if (credits && docredits)  
  225.   { bottom -= (8.0 / 72.0);
  226.     printf ("/Times-Roman findfont 8 scalefont setfont\n");
  227.     printf ("%lg inch %lg inch moveto\n", width, bottom);
  228.     printf ("(%s)\n", ps_chars (credits));
  229.     printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n");
  230.   }
  231.   else if (dosize)
  232.   { bottom -= (8.0 / 72.0);
  233.     printf ("/Times-Roman findfont 8 scalefont setfont\n");
  234.     printf ("%lg inch %lg inch moveto\n", width, bottom);
  235.     sprintf (buf, "[ %d by %d pixels, %1.3lf %s, %1.2lf by %1.2lf inches ]",
  236.          image.hdr.cols, image.hdr.rows, image.hdr.aspect,
  237.          "aspect ratio", width, height);
  238.     printf ("(%s)\n", ps_chars (buf));
  239.     printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n");
  240.   }
  241.  
  242.   if (dobanner && banner)
  243.   { printf ("/Times-Bold findfont 28 scalefont setfont\n");
  244.     printf ("%lg inch %lg inch moveto\n", width/2.0, top);
  245.     printf ("(%s)\n", ps_chars (banner));
  246.     printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
  247.  
  248.     top += (28.0 / 72.0) + 0.125;
  249.     bottom -= (28.0 / 72.0);
  250.  
  251.     printf ("%lg inch %lg inch moveto\n", width/2.0, bottom);
  252.     printf ("(%s)\n", ps_chars (banner));
  253.     printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
  254.   }
  255.  
  256.   printf ("%lg inch %lg inch scale\n", width, height);
  257.   write_simple_ps (&image, stdout, iscolor, bits, padlen);
  258.   
  259.   printf ("grestore\n");
  260.  
  261.   if (!scribe)
  262.   { printf ("\nshowpage\n\n");
  263.     printf ("%%%%Trailer\n");
  264.   }
  265.  
  266.   exit (0);
  267. }
  268.  
  269. /****************************************************************
  270.  * ps_chars: Put in proper escapes so an arbitrary string works
  271.  *         according to the PostScript definition of a literal
  272.  ****************************************************************/
  273.  
  274. char *ps_chars (txt)
  275. char *txt;
  276. { static char buf[512];
  277.   register char *s = buf;
  278.   char *index ();
  279.   
  280.   for (; *txt; txt++)
  281.   { if (index ("()\\", *txt))
  282.     { *s++ = '\\'; *s++ = *txt; }
  283.     else if (*txt < ' ' || *txt > '~')
  284.     { sprintf (s, "\\%03o", *txt & 0377); s += 4; }
  285.     else
  286.     { *s++ = *txt; }
  287.   }
  288.   *s = '\0';
  289.   s = buf;
  290.   return (s);
  291. }
  292.